#include "collectioneditmodel.h"


#include <QDebug>
#include <QMetaProperty>


CollectionEditModel::CollectionEditModel(QObject *parent) :
    QAbstractItemModel(parent)
{
}


void CollectionEditModel::setCollection(Collection *collection)
{
    beginResetModel();
    m_collection = collection;
    endResetModel();
}


Collection *CollectionEditModel::collection() const
{
    return m_collection;
}


QModelIndex CollectionEditModel::index(int row, int column, const QModelIndex &parent) const
{
    if (m_collection.isNull() || !hasIndex(row, column, parent)) return QModelIndex();
    if (!parent.isValid())
    {
        int propertyCount = m_collection->metaObject()->propertyCount();
        if (row < propertyCount)
        {
            return createIndex(row, column, m_collection.data());
        }

        QList<AbstractModelItem*> childItems = m_collection->childItems();
        int childPos = row - propertyCount;
        if (childPos < 0 || childPos >= childItems.count())
        {
            qDebug() << Q_FUNC_INFO << "Collection childPos is invalid:" << childPos;
            return QModelIndex();
        }

        AbstractModelItem* item = childItems.at(childPos);
        if (!item)
        {
            qDebug() << Q_FUNC_INFO << "Child item is null at pos:" << childPos;
            return QModelIndex();
        }

        return createIndex(row, column, item);
    }

    return QModelIndex();
}


QModelIndex CollectionEditModel::parent(const QModelIndex &child) const
{
    if (m_collection.isNull() || !child.isValid()) return QModelIndex();

    AbstractModelItem* item = reinterpret_cast<AbstractModelItem*>(child.internalPointer());
    if (!item)
    {
        return QModelIndex();
    }

    if (item == m_collection || item->parent() == m_collection)
    {
        return QModelIndex();
    }


    // todo: resolve row
    return QModelIndex();
}


int CollectionEditModel::rowCount(const QModelIndex &parent) const
{
    if (m_collection.isNull()) return 0;

    int rows = 0;
    if (!parent.isValid())
    {
        rows = m_collection->metaObject()->propertyCount();
        rows += m_collection->childItems().count();
        return rows;
    }

    AbstractModelItem* item = reinterpret_cast<AbstractModelItem*>(parent.internalPointer());
    if (item = m_collection.data()) return 0;

    return item->childItems().count();
}


int CollectionEditModel::columnCount(const QModelIndex &parent) const
{
    return 2;
}


QVariant CollectionEditModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || role != Qt::DisplayRole)
    {
        return QVariant();
    }

    AbstractModelItem* item = reinterpret_cast<AbstractModelItem*>(index.internalPointer());
    if (!item)
    {
        return QVariant();
    }

    if (item == m_collection)
    {
        if (index.row() >= m_collection->metaObject()->propertyCount())
        {
            return QVariant();
        }

        const char* propertyName = m_collection->metaObject()->property(index.row()).name();
        switch (index.column())
        {
        case Field_NAME:
            return QString(propertyName);

        case Field_VALUE:
            return m_collection->property(propertyName);

        default:
            break;
        }

        return QVariant();
    }

    if (item->parent() == m_collection)
    {
        if (index.column() == Field_VALUE)
        {
            return QVariant();
        }

        return item->value(0);
    }

    return QVariant();
}


bool CollectionEditModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    return false;
}


Qt::ItemFlags CollectionEditModel::flags(const QModelIndex &index) const
{
    return QAbstractItemModel::flags(index);
}


